package com.sad.jetpack.v1.datamodel.api.extension.interceptor;
import android.text.TextUtils;

import com.sad.jetpack.v1.datamodel.api.DataSource;
import com.sad.jetpack.v1.datamodel.api.IDataModelChainInput;
import com.sad.jetpack.v1.datamodel.api.IDataModelChainOutput;
import com.sad.jetpack.v1.datamodel.api.IDataModelInterceptorInput;
import com.sad.jetpack.v1.datamodel.api.IDataModelInterceptorOutput;
import com.sad.jetpack.v1.datamodel.api.IDataModelResponse;
import com.sad.jetpack.v1.datamodel.api.extension.cache.ICacheEntity;
import com.sad.jetpack.v1.datamodel.api.utils.LogcatUtils;

public class SimpleStringCacheDataModelInterceptor implements IDataModelInterceptorInput<String>, IDataModelInterceptorOutput<String> {
    final static int DEFAULT_CACHE_HFAT =5;//高频访问分界点(单位s)
    private IStringCacheDataConverter<String> cacheDataConverter;
    private ICacheLoader<String> cacheLoader;
    private int thisIndex=0;
    private int cacheHighFrequencyAccessTimeThresholdSeconds=DEFAULT_CACHE_HFAT;//高频访问时间阈值

    public int getCacheHighFrequencyAccessTimeThresholdSeconds() {
        return cacheHighFrequencyAccessTimeThresholdSeconds;
    }

    public void setCacheHighFrequencyAccessTimeThresholdSeconds(int cacheHighFrequencyAccessTimeThresholdSeconds) {
        this.cacheHighFrequencyAccessTimeThresholdSeconds = cacheHighFrequencyAccessTimeThresholdSeconds;
    }

    public void setCacheLoader(ICacheLoader<String> cacheLoader) {
        this.cacheLoader = cacheLoader;
    }

    public ICacheLoader<String> getCacheLoader() {
        return cacheLoader;
    }

    public IStringCacheDataConverter<String> getCacheDataConverter() {
        return cacheDataConverter;
    }

    public void setCacheDataConverter(IStringCacheDataConverter<String> cacheDataConverter) {
        this.cacheDataConverter = cacheDataConverter;
    }

    public SimpleStringCacheDataModelInterceptor() {
        this(new DefaultCacheLoader(),new DefaultStringCacheDataConverter());
    }
    public SimpleStringCacheDataModelInterceptor(ICacheLoader<String> cacheLoader) {
        this(cacheLoader,new DefaultStringCacheDataConverter());
    }
    public SimpleStringCacheDataModelInterceptor(
                                                 ICacheLoader<String> cacheLoader,
                                                 IStringCacheDataConverter<String> cacheDataConverter

    ) {
        this.cacheDataConverter=cacheDataConverter;
        this.cacheLoader=cacheLoader;
    }

    @Override
    public void onInterceptedInput(IDataModelChainInput< String> chainInput) throws Exception {
        this.thisIndex=chainInput.currIndex();
        //策略：
        // 内容返回型接口：
        //                     10s内：仅返回缓存。缓存空则访问数据源。
        //                     10s-3600s：直接访问数据源。
         //提交数据型接口：直接请求数据源，缓存不读不写。
        try {

            String key=cacheDataConverter.createKeyFromRequest(chainInput.request());
            ICacheEntity<String> cacheEntity= cacheLoader.readCache(key);
            if (cacheEntity==null){
                //无缓存,直接走下一步
                chainInput.proceed();
            }
            else {
                //开始根据策略判断执行
                long createTime=cacheEntity.createTime();
                long cx=(System.currentTimeMillis()-createTime)/1000;
                LogcatUtils.e("----->读取缓存：createTime="+createTime+",距今="+cx);
                String cacheValue=cacheEntity.cacheValue();
                if (!TextUtils.isEmpty(cacheValue)){
                    IDataModelResponse<String> cacheResponse=cacheDataConverter.deserializeString(chainInput.request(), cacheValue);
                    LogcatUtils.e("----->读取缓存：key="+key+",value="+cacheResponse);
                    if (cx<= getCacheHighFrequencyAccessTimeThresholdSeconds()){
                        LogcatUtils.e("----->读取缓存："+getCacheHighFrequencyAccessTimeThresholdSeconds()+"s内");
                        //10s内重复访问，直接返回缓存，无需再访问数据源
                        chainInput.proceed(chainInput.request(), cacheResponse,thisIndex);
                    }
                    else{
                        LogcatUtils.e("----->直接访问数据源："+getCacheHighFrequencyAccessTimeThresholdSeconds()+"s以上");
                        //10s-3600s，直接访问数据源
                        chainInput.proceed();
                    }

                }
                else {
                    chainInput.proceed();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            chainInput.proceed();
        }
    }

    @Override
    public String tag() {
        return IDataModelInterceptorInput.super.tag();
    }

    @Override
    public void onInterceptedOutput(IDataModelChainOutput< String> chainOutput) throws Exception {
        try{
            if (chainOutput.response().dataSource()!=DataSource.CACHE){
                String key=cacheDataConverter.createKeyFromRequest(chainOutput.response().request());
                String value=cacheDataConverter.serializeResponse(chainOutput.response());
                if (cacheLoader!=null){
                    cacheLoader.writeCache(key,value);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        chainOutput.proceed();
    }
}
